#include <buola/scene/cvertexdata.h>
#include <buola/gl.h>

namespace buola { namespace scene {

CVertexData::CVertexData()
    :   mVBO(0)
    ,   mVertexSize(0)
//    ,   mVertexCapacity(0)
{

}

CVertexData::~CVertexData()
{
    for(int i=0;i<mFields.size();i++)
        delete mFields[i];
}

void CVertexData::Resize(int pCount)
{
    if(!mVBO)
        glGenBuffers(1,&mVBO);

    glBindBuffer(GL_ARRAY_BUFFER,mVBO);
    glBufferData(GL_ARRAY_BUFFER,pCount*mVertexSize,nullptr,GL_STATIC_DRAW);

    mVertexCount=pCount;
}

void *CVertexData::Map(GLenum pType)
{
    glBindBuffer(GL_ARRAY_BUFFER,mVBO);
    return glMapBuffer(GL_ARRAY_BUFFER,pType);
}

void CVertexData::Unmap()
{
    glUnmapBuffer(GL_ARRAY_BUFFER);
}

void CVertexData::SetVertexAttrib(int pIndex,EFieldSemanticType pType)
{
    for(SField *lField : mFields)
    {
        if(lField->mSemanticType==pType)
        {
            glVertexAttribPointer(pIndex,lField->mCount,lField->mDataType,false,mVertexSize,
                                  (void*)(ptrdiff_t)lField->mOffset);
            return;
        }
    }
}

void CVertexData::DoAddField(EFieldSemanticType pSemanticType,GLenum pDataType,int pElementSize,
                             int pCount,const std::string &pName)
{
    SField *lField=new SField;
    lField->mName=pName;
    lField->mSemanticType=pSemanticType;
    lField->mDataType=pDataType;
    lField->mElementSize=pElementSize;
    lField->mCount=pCount;
    lField->mFieldSize=lField->mElementSize*lField->mCount;
    lField->mFieldSize=4*((lField->mFieldSize+3)/4);
    lField->mOffset=mVertexSize;
    mVertexSize+=lField->mFieldSize;
    mFields.push_back(lField);
}

/*namespace gl*/ } /*namespace buola*/ }
